package com.dhcc.sds.task;


import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.dhcc.cdc.busi.entity.CdcDictionaryEntity;
import com.dhcc.cdc.busi.entity.CdcOrdmastEntity;
import com.dhcc.cdc.busi.service.ICdcDictionaryService;
import com.dhcc.cdc.busi.service.ICdcOrdmastService;
import com.dhcc.cdc.sys.cache.config.CdcConfigCache;
import com.dhcc.cdc.sys.entity.ConfigurationEntity;
import com.dhcc.cdc.sys.service.IConfigurationService;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.sdc.base.entity.CdssRecommendKeywordEntity;
import com.dhcc.sdc.base.entity.SdcBaseAssessmentEntity;
import com.dhcc.sdc.base.service.ICdssRecommendKeywordService;
import com.dhcc.sdc.base.service.ISdcBaseAssessmentService;
import com.dhcc.sdc.cdss.dao.SdcCdssItemMatchMapper;
import com.dhcc.sdc.cdss.entity.SdcCdssItemMatchEntity;
import com.dhcc.sdc.cdss.service.ISdcCdssItemMatchService;
import com.dhcc.sds.standard.dao.SdsStandOrderMatchMapper;
import com.dhcc.sds.standard.dto.CdcOrdmastDto;

import com.dhcc.sds.standard.entity.SdsStandDicMatchParamEntity;
import com.dhcc.sds.standard.entity.SdsStandOrderMatchEntity;

import com.dhcc.sds.standard.service.ISdsStandDicMatchParamService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 医嘱字典更新自动更新
 *  标准化医嘱对照
 *  诊疗方案对照医嘱
 */
@Service("autoUpdateCompareTask")
public class AutoUpdateCompareTask {

    @Autowired
    private IConfigurationService configurationService;
    @Autowired
    private ICdcOrdmastService cdcOrdmastService;
    @Autowired
    private ISdsStandDicMatchParamService sdsStandDicMatchParamService;
    @Autowired
    private ICdcDictionaryService cdcDictionaryService;
    @Resource
    private SdsStandOrderMatchMapper sdsStandOrderMatchMapper;
    @Autowired
    private ISdcCdssItemMatchService sdcCdssItemMatchService;
    @Autowired
    private ISdcBaseAssessmentService sdcBaseAssessmentService;
    @Autowired
    private ICdssRecommendKeywordService cdssRecommendKeywordService;
    @Resource
    private SdcCdssItemMatchMapper sdcCdssItemMatchMapper;

    public void autoUpdateCompare(){
        Date date = new Date();
        String formatNow = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
        String formatLastWeek = com.dhcc.sds.util.DateUtil.getDayDate(-7, "yyyy-MM-dd HH:mm:ss");


        //是否启用自动更新标化字典对照任务
        String enableOrderCompare = CdcConfigCache.me().getValueByKey("SDS", "SDFormCheckType");
        if ("Y".equals(enableOrderCompare)){
            Wrapper<CdcOrdmastEntity> mrWpr = new EntityWrapper<>();
            mrWpr.ge("UPDATE_DATE", formatLastWeek);
            mrWpr.le("UPDATE_DATE", formatNow);
            mrWpr.eq("is_active", 1);
            List<CdcOrdmastEntity> ordmastEntities = cdcOrdmastService.selectList(mrWpr);
            if (!ordmastEntities.isEmpty()){
                //compareOrder(ordmastEntities);
            }
        }

        //是否启用自动更新诊疗方案对照任务
        String enableCDSSCompare = CdcConfigCache.me().getValueByKey("SDS", "SDFormCheckType");
        if ("Y".equals(enableCDSSCompare)){
            Wrapper<SdcBaseAssessmentEntity> mrWpr = new EntityWrapper<>();
            mrWpr.ge("UPDATE_DATE", formatLastWeek);
            mrWpr.le("UPDATE_DATE", formatNow);
            mrWpr.eq("is_active", 1);
            List<SdcBaseAssessmentEntity> baseAssessmentEntities = sdcBaseAssessmentService.selectList(mrWpr);
            if (!baseAssessmentEntities.isEmpty()){
                compareAssessment(baseAssessmentEntities);
            }
        }

    }

    /*private void compareOrder(List<CdcOrdmastEntity> cdcOrdmastEntities){
        //医嘱对照数据源：非抗菌药物、抗菌药物、处置操作
        List<SdsStandDicMatchParamEntity> standDicMatchEntities = sdsStandDicMatchParamService.getDicBySource(Arrays.asList("非抗菌药物", "抗菌药物", "处置操作"));
        List<SdsStandDicMatchParamEntity> standDicsubMatchEntities = sdsStandDicMatchParamService.getDicsubBySource(Arrays.asList("非抗菌药物", "抗菌药物", "处置操作"));
        //不对照护理医嘱
        CdcDictionaryEntity cdcDictionaryEntity = cdcDictionaryService.queryByTypeCodeAndCode("OrdData", "bus_order_cate", "护理");
        List<CdcOrdmastEntity> collect = cdcOrdmastEntities.stream().filter(busOrderCateId -> !cdcDictionaryEntity.getId().equals(busOrderCateId)).collect(Collectors.toList());
        List<CdcOrdmastDto> cdcOrdmastDtos = collect.stream().map(t ->{
            CdcOrdmastDto cdcOrdmastDto = new CdcOrdmastDto();
            BeanUtils.copyProperties(t, cdcOrdmastDto);
            return cdcOrdmastDto;
        }).collect(Collectors.toList());

        Map<Long, List<SdsStandDicMatchEntity>> dicMatchMap = new HashMap<>();
        Map<Long, List<SdsStandDicMatchEntity>> dicsubMatchMap = new HashMap<>();

        //处理dic数据
        for (SdsStandDicMatchEntity standDicMatchEntity : standDicMatchEntities){
            if (CommonUtil.isEmpty(dicMatchMap.get(standDicMatchEntity.getDicId()))){
                List<SdsStandDicMatchEntity> dicMatchEntities = new ArrayList<>();
                dicMatchEntities.add(standDicMatchEntity);
                dicMatchMap.put(standDicMatchEntity.getDicId(), dicMatchEntities);
            }else {
                List<SdsStandDicMatchEntity> dicMatchEntities = dicMatchMap.get(standDicMatchEntity.getDicId());
                dicMatchEntities.add(standDicMatchEntity);
            }
        }
        //处理dicsub数据
        for (SdsStandDicMatchEntity standDicMatchEntity : standDicsubMatchEntities){
            if (CommonUtil.isEmpty(dicsubMatchMap.get(standDicMatchEntity.getDicsubId()))){
                List<SdsStandDicMatchEntity> dicMatchEntities = new ArrayList<>();
                dicMatchEntities.add(standDicMatchEntity);
                dicsubMatchMap.put(standDicMatchEntity.getDicsubId(), dicMatchEntities);
            }else {
                List<SdsStandDicMatchEntity> dicMatchEntities = dicsubMatchMap.get(standDicMatchEntity.getDicsubId());
                dicMatchEntities.add(standDicMatchEntity);
            }
        }
        List<SdsStandOrderMatchEntity> sdsStandOrderMatchEntities = new ArrayList<>();
        //标准字典与医嘱项对照
        Map<Long, List<CdcOrdmastDto>> ordmastMap = new HashMap<>();
        for (Long dicId : dicMatchMap.keySet()){
            List<SdsStandDicMatchEntity> dicMatchEntities = dicMatchMap.get(dicId);
            String filterTxt = "";
            List<CdcOrdmastDto> matchOrdmast = new ArrayList<>();
            a:for (SdsStandDicMatchEntity standDicMatchEntity : dicMatchEntities){
                String filterType = standDicMatchEntity.getFilterType();
                String matchTxt = standDicMatchEntity.getMatchTxt();
                String matchType = standDicMatchEntity.getMatchType();
                if (Objects.equals("O", filterType)){
                    filterTxt = filterTxt + matchType + ":" + matchTxt + ",";
                    continue a;
                }
                for (CdcOrdmastDto cdcOrdmastDto : cdcOrdmastDtos){
                    String drugCommonName = cdcOrdmastDto.getDrugCommonName();
                    String description = cdcOrdmastDto.getDescription();
                    //处理并且关系的关键字:&分隔的关键字同时满足
                    boolean checkFlg = true;
                    if (matchTxt.contains("&")){
                        String[] split = matchTxt.split("&");
                        if (Objects.equals("C", matchType)){
                            b:for (String s : split){
                                if (!drugCommonName.contains(s)){
                                    checkFlg = false;
                                    break b;
                                }
                            }
                            if (checkFlg){
                                cdcOrdmastDto.setMatchType("C");
                                matchOrdmast.add(cdcOrdmastDto);
                                ordmastMap.put(dicId, matchOrdmast);
                            }
                        }else if (Objects.equals("K", matchType)){
                            b:for (String s : split){
                                if (StringUtils.isEmpty(drugCommonName)){
                                    if (!description.contains(s)){
                                        checkFlg = false;
                                        break b;
                                    }
                                }else {
                                    if (!description.contains(s) && !drugCommonName.contains(s)){
                                        checkFlg = false;
                                        break b;
                                    }
                                }
                            }
                            if (checkFlg){
                                cdcOrdmastDto.setMatchType("K");
                                matchOrdmast.add(cdcOrdmastDto);
                                ordmastMap.put(dicId, matchOrdmast);
                            }
                        }
                    }else {
                        if (Objects.equals("C", matchType)){
                            if (drugCommonName.contains(matchTxt)){
                                cdcOrdmastDto.setMatchType("C");
                                matchOrdmast.add(cdcOrdmastDto);
                                ordmastMap.put(dicId, matchOrdmast);
                            }
                        }else if (Objects.equals("K", matchType)){
                            //drugCommonName可能为空
                            if (StringUtils.isEmpty(drugCommonName)){
                                if (description.contains(matchTxt)){
                                    cdcOrdmastDto.setMatchType("K");
                                    matchOrdmast.add(cdcOrdmastDto);
                                    ordmastMap.put(dicId, matchOrdmast);
                                }
                            }else {
                                if (description.contains(matchTxt) || drugCommonName.contains(matchTxt)){
                                    cdcOrdmastDto.setMatchType("K");
                                    matchOrdmast.add(cdcOrdmastDto);
                                    ordmastMap.put(dicId, matchOrdmast);
                                }
                            }
                        }
                    }
                }
            }
            //排除
            if (!StringUtils.isEmpty(filterTxt)){
                String[] split = filterTxt.split(",");
                List<CdcOrdmastDto> ordmastEntities = ordmastMap.get(dicId);
                Iterator<CdcOrdmastDto> it = ordmastEntities.iterator();
                while (it.hasNext()){
                    CdcOrdmastDto ordmastEntity = it.next();
                    for (String s : split){
                        String[] split1 = s.split(":");
                        if (Objects.equals("C", split1[0])){
                            if (ordmastEntity.getDrugCommonName().contains(split1[1])){
                                it.remove();
                            }
                        }else if (Objects.equals("K", split1[0])){
                            if (StringUtils.isEmpty(ordmastEntity.getDrugCommonName())){
                                if (ordmastEntity.getDescription().contains(split1[1])){
                                    it.remove();
                                }
                            }else {
                                if (ordmastEntity.getDescription().contains(split1[1]) || ordmastEntity.getDrugCommonName().contains(split1[1])){
                                    it.remove();
                                }
                            }
                        }

                    }
                }
                ordmastMap.put(dicId, ordmastEntities);
            }
        }
        for (Long dicId : ordmastMap.keySet()){
            List<CdcOrdmastDto> ordmastEntities = ordmastMap.get(dicId);
            for (CdcOrdmastDto cdcOrdmastEntity : ordmastEntities){
                SdsStandOrderMatchEntity standOrderMatchEntity = new SdsStandOrderMatchEntity();
                standOrderMatchEntity.setDicId(dicId);
                standOrderMatchEntity.setOrdmastId(cdcOrdmastEntity.getId());
                SdsStandOrderMatchEntity standOrderMatchEntity1 = sdsStandOrderMatchMapper.selectOne(standOrderMatchEntity);
                if (StringUtils.isEmpty(standOrderMatchEntity1)) {
                    standOrderMatchEntity.setMatchType(cdcOrdmastEntity.getMatchType());
                    standOrderMatchEntity.setMatchDate(new Date());
                    sdsStandOrderMatchEntities.add(standOrderMatchEntity);
                }
            }
        }
        //标准字典子项与医嘱项对照
        Map<Long, List<CdcOrdmastDto>> ordmastMap2 = new HashMap<>();
        for (Long dicsubId : dicsubMatchMap.keySet()){
            List<SdsStandDicMatchEntity> dicMatchEntities = dicsubMatchMap.get(dicsubId);
            String filterTxt = "";
            List<CdcOrdmastDto> matchOrdmast = new ArrayList<>();
            a:for (SdsStandDicMatchEntity standDicMatchEntity : dicMatchEntities){
                String filterType = standDicMatchEntity.getFilterType();
                String matchTxt = standDicMatchEntity.getMatchTxt();
                String matchType = standDicMatchEntity.getMatchType();
                if (Objects.equals("O", filterType)){
                    filterTxt = filterTxt + matchType + ":" + matchTxt + ",";
                    continue a;
                }
                for (CdcOrdmastDto ordmastEntity : cdcOrdmastDtos){
                    String drugCommonName = ordmastEntity.getDrugCommonName();
                    String description = ordmastEntity.getDescription();
                    ////处理并且关系的关键字:&分隔的关键字同时满足
                    boolean checkFlg = true;
                    if (matchTxt.contains("&")){
                        String[] split = matchTxt.split("&");
                        if (Objects.equals("C", matchType)){
                            b:for (String s : split){
                                if (!drugCommonName.contains(s)){
                                    checkFlg = false;
                                    break b;
                                }
                            }
                            if (checkFlg){
                                ordmastEntity.setMatchType("C");
                                matchOrdmast.add(ordmastEntity);
                                ordmastMap2.put(dicsubId, matchOrdmast);
                            }
                        }else if (Objects.equals("K", matchType)){
                            b:for (String s : split){
                                if (StringUtils.isEmpty(drugCommonName)){
                                    if (!description.contains(s)){
                                        checkFlg = false;
                                        break b;
                                    }
                                }else {
                                    if (!description.contains(s) && !drugCommonName.contains(s)){
                                        checkFlg = false;
                                        break b;
                                    }
                                }
                            }
                            if (checkFlg){
                                ordmastEntity.setMatchType("K");
                                matchOrdmast.add(ordmastEntity);
                                ordmastMap2.put(dicsubId, matchOrdmast);
                            }
                        }
                    }else {
                        if (Objects.equals("C", matchType)){
                            if (drugCommonName.contains(matchTxt)){
                                ordmastEntity.setMatchType("C");
                                matchOrdmast.add(ordmastEntity);
                                ordmastMap2.put(dicsubId, matchOrdmast);
                            }
                        }else if (Objects.equals("K", matchType)){
                            //drugCommonName可能为空
                            if (StringUtils.isEmpty(drugCommonName)){
                                if (description.contains(matchTxt)){
                                    ordmastEntity.setMatchType("K");
                                    matchOrdmast.add(ordmastEntity);
                                    ordmastMap2.put(dicsubId, matchOrdmast);
                                }
                            }else {
                                if (description.contains(matchTxt) || drugCommonName.contains(matchTxt)){
                                    ordmastEntity.setMatchType("K");
                                    matchOrdmast.add(ordmastEntity);
                                    ordmastMap2.put(dicsubId, matchOrdmast);
                                }
                            }
                        }
                    }
                }
            }
            //排除
            if (!StringUtils.isEmpty(filterTxt)){
                String[] split = filterTxt.split(",");
                List<CdcOrdmastDto> ordmastEntities = ordmastMap2.get(dicsubId);
                Iterator<CdcOrdmastDto> it = ordmastEntities.iterator();
                while (it.hasNext()){
                    CdcOrdmastDto ordmastEntity = it.next();
                    for (String s : split){
                        String[] split1 = s.split(":");
                        if (Objects.equals("C", split1[0])){
                            if (ordmastEntity.getDrugCommonName().contains(split1[1])){
                                it.remove();
                            }
                        }else if (Objects.equals("K", split1[0])){
                            if (StringUtils.isEmpty(ordmastEntity.getDrugCommonName())){
                                if (ordmastEntity.getDescription().contains(split1[1])){
                                    it.remove();
                                }
                            }else {
                                if (ordmastEntity.getDescription().contains(split1[1]) || ordmastEntity.getDrugCommonName().contains(split1[1])){
                                    it.remove();
                                }
                            }
                        }

                    }
                }
                ordmastMap2.put(dicsubId, ordmastEntities);
            }

        }
        for (Long dicsubId : ordmastMap2.keySet()){
            List<CdcOrdmastDto> ordmastEntities = ordmastMap2.get(dicsubId);
            for (CdcOrdmastDto cdcOrdmastEntity : ordmastEntities){
                SdsStandOrderMatchEntity standOrderMatchEntity = new SdsStandOrderMatchEntity();
                standOrderMatchEntity.setDicsubId(dicsubId);
                standOrderMatchEntity.setOrdmastId(cdcOrdmastEntity.getId());
                SdsStandOrderMatchEntity standOrderMatchEntity1 = sdsStandOrderMatchMapper.selectOne(standOrderMatchEntity);
                if (StringUtils.isEmpty(standOrderMatchEntity1)) {
                    standOrderMatchEntity.setMatchType(cdcOrdmastEntity.getMatchType());
                    standOrderMatchEntity.setMatchDate(new Date());
                    sdsStandOrderMatchEntities.add(standOrderMatchEntity);
                }
            }
        }
        sdsStandOrderMatchMapper.insertBatch(sdsStandOrderMatchEntities);
    }*/

    private void compareAssessment(List<SdcBaseAssessmentEntity> baseAssessmentEntities){
        List<CdssRecommendKeywordEntity> cdssRecommendKeywordEntities = cdssRecommendKeywordService.selectList(new EntityWrapper<CdssRecommendKeywordEntity>()
            .eq("recommend_type", "推荐评估量表"));
        for (CdssRecommendKeywordEntity cdssRecommendKeywordEntity : cdssRecommendKeywordEntities) {
            String recommendType = cdssRecommendKeywordEntity.getRecommendType();
            String keyword = cdssRecommendKeywordEntity.getKeyword();
            String[] split = keyword.split(",");

            List<String> list = this.handleEvalRegexp(split);

            //排除sql
            String filterTxt = list.get(0);
            //同时满足sql
            String keywordAndTxt = list.get(1);
            //满足一个sql
            String keywordOrTxt = list.get(2);
            List<Long> matchIds = new ArrayList<>();
            matchIds = sdcCdssItemMatchMapper.compareEvalByRegexp(filterTxt, keywordAndTxt, keywordOrTxt);

            List<SdcCdssItemMatchEntity> sdcCdssItemMatchEntities = new ArrayList<>();
            for (Long matchId : matchIds) {
                SdcCdssItemMatchEntity sdcCdssItemMatchEntity = new SdcCdssItemMatchEntity();
                sdcCdssItemMatchEntity.setItemId(cdssRecommendKeywordEntity.getItemId());
                sdcCdssItemMatchEntity.setMatchId(matchId);
                SdcCdssItemMatchEntity cdssItemMatchEntity = sdcCdssItemMatchMapper.selectOne(sdcCdssItemMatchEntity);
                if (StringUtils.isEmpty(cdssItemMatchEntity)) {
                    sdcCdssItemMatchEntity.setMatchDate(new Date());
                    sdcCdssItemMatchEntities.add(sdcCdssItemMatchEntity);
                }
            }
            if (null != sdcCdssItemMatchEntities && sdcCdssItemMatchEntities.size() > 0) {
                sdcCdssItemMatchMapper.insertBatch(sdcCdssItemMatchEntities);
            }
        }

        
    }


    private List<String> handleEvalRegexp(String[] split) {
        List<String> res = new ArrayList<>();
        //排除sql
        String filterTxt = "";
        //同时满足sql
        String keywordAndTxt = "";
        //满足一个sql
        String keywordOrTxt = "";
        for (String s1 : split) {
            if (s1.contains("!")) {
                filterTxt = filterTxt + "," + s1.substring(1, s1.length());
            } else if (s1.contains("&")) {
                //同时满足
                String[] split1 = s1.split("&");
                for (int i = 0; i <= split1.length - 1; i++) {
                    if (i == 0) {
                        keywordAndTxt = keywordAndTxt + " or code = '" + split1[0] + "'";
                    } else {
                        keywordAndTxt = keywordAndTxt + " and code = '" + split1[i] + "'";
                    }
                }
                //keywordAndTxt = keywordAndTxt + " or description like '%" + split1[0] + "%' and description like '%" + split1[1] + "%'";
            } else {
                keywordOrTxt = keywordOrTxt + "," + s1;
            }
        }
        if ("" != filterTxt) {
            filterTxt = filterTxt.substring(1, filterTxt.length());
        }
        if ("" != keywordOrTxt) {
            keywordOrTxt = keywordOrTxt.substring(1, keywordOrTxt.length());
        }
        if ("" != keywordAndTxt && "" == keywordOrTxt) {
            keywordAndTxt = keywordAndTxt.replaceFirst("or", "and");
        }
        res.add(filterTxt);
        res.add(keywordAndTxt);
        res.add(keywordOrTxt);
        return res;
    }

}
